package com.gao.a_buffer.c;

import org.junit.Test;

import java.nio.ByteBuffer;

/**
 * @author gao
 * @time 2020/06/18 11:37:47
 *
 * ByteBuffer的方法
 */
public class App {
    
    // ByteBbuffer的mark()和reset()方法
    @Test
    public void test() {
        ByteBuffer buf = ByteBuffer.allocate(10);
        buf.put("a".getBytes());
        buf.put("b".getBytes());
        buf.put("c".getBytes());
        // 做记号
        buf.mark();
        buf.put("d".getBytes());
        buf.put("e".getBytes());
        buf.put("f".getBytes());
        // 让position回到记号处
        buf.reset();
        while (buf.hasRemaining()) {
            System.out.print((char)buf.get());
        }
    }
    
    // ByteBuffer的flip方法
    @Test
    public void test2() {
        ByteBuffer buf = ByteBuffer.allocate(10);
        buf.put("1234567".getBytes());
        // buf.flip()等价于先调用了buf.limit(buf.position())，
        // 再调用buf.position(0)
        buf.flip();

        while (buf.hasRemaining()) {
            System.out.print((char) (buf.get()));
        }
    }

    // ByteBuffer的clear方法
    @Test
    public void test3() {
        ByteBuffer buf = ByteBuffer.allocate(10);
        // 将缓冲区填充满
        buf.put("1234567890".getBytes());
        // buf.clear()等价于先调用buf.limit(buf.capacity())，再调用buf.position(0)
        // 注意buf.clear仅仅是修改limit和position的值而已，它并不会清除缓冲区中的数据。
        buf.clear();
        buf.put("abcdefg".getBytes());
        buf.flip();
        while (buf.hasRemaining()) {
            System.out.print((char)buf.get());
        }
        // output：abcdefg890，证明了clear并不会清除缓冲区中的数据
        System.out.println("\n" + new String(buf.array()));
    }

    // ByteBuffer的compact()方法的使用
    @Test
    public void test4() {
        ByteBuffer buf = ByteBuffer.allocate(10);
        buf.put("123456".getBytes());
        System.out.println("position\t" + buf.position());  // 6
        System.out.println("limit\t" + buf.limit());        // 10
        System.out.println("capacity\t" + buf.capacity());  // 10

        buf.flip();
        buf.get();
        buf.get();
        buf.get();

        System.out.println("=========================================");

        System.out.println("position\t" + buf.position());  // 3
        System.out.println("limit\t" + buf.limit());        // 6
        System.out.println("capacity\t" + buf.capacity());  // 10

        System.out.println("=========================================");

        // buf.compact()的作用
        // 1. buf.position(buf.limit() - buf.position())， buf.limit(buf.capacity())
        // 2. 将缓冲区中还没有读取到的数据，向前移动，“顶住”最开头。
        buf.compact();
        System.out.println("position\t" + buf.position());
        System.out.println("limit\t" + buf.limit());
        System.out.println("capacity\t" + buf.capacity());

        // 456456， 因为上面读取过123了，剩下的456就被移动到开头了
        System.out.println(new String(buf.array()));

        // 此时应该调用一下flip，保证position为0，limit为3，再使用buf.get()方法获取数据，
        // 刚好只能获取出456
        buf.flip();

        while(buf.hasRemaining()) {
            System.out.println((char)buf.get());
        }

    }

    // ByteBuffer的rewind()方法的使用
    @Test
    public void test5() {
        ByteBuffer buf = ByteBuffer.allocate(10);
        buf.put("1234567".getBytes());
        buf.flip();
        System.out.println((char)buf.get());
        System.out.println((char)buf.get());
        System.out.println((char)buf.get());
        // buf.rewind()，仅仅是把position设置为0，limit没有变化。
        buf.rewind();
        System.out.println((char)buf.get());
        System.out.println((char)buf.get());
        System.out.println((char)buf.get());
        System.out.println((char)buf.get());
        System.out.println((char)buf.get());
    }

    // ByteBuffer的wrap()方法的使用
    @Test
    public void test6() {
        byte[] bb = {97, 98, 99};
        // ByteBuffer的wrap()方法，会创建一个缓冲区，并且用一个字节数组来填充这个缓冲区
        ByteBuffer buf = ByteBuffer.wrap(bb);
        System.out.println("position\t" + buf.position());
        System.out.println("limit\t" + buf.limit());
        System.out.println("capacity\t" + buf.capacity());

        while (buf.hasRemaining()) {
            System.out.print((char)buf.get());
        }
    }

}
